/** @file bt_def.h
  *
  * @brief This file contains the generic definitions 
  * of Bluetooth driver.
  * 
  * (c) Copyright 2003-2007, Marvell International Ltd.
  * All Rights Reserved
  */

#ifndef _BT_DEF_H_
#define _BT_DEF_H_


#undef MRVL_BUILTIN

// String of the interface and chip
#define IFSTRN		"SDIO"
#define CHIPSTRN	"8688"

#define MRVL_MEMORY_TAG  'MRBT'

#ifndef MAX
#define MAX(a,b)        ((a) > (b) ? (a) : (b))
#endif

//
// Allocate and release tagged memory
//
#define MRVDRV_ALLOC_MEM(_length) SDAllocateMemoryWithTag((_length), MRVL_MEMORY_TAG)
#define MRVDRV_FREE_MEM(_buffer)  SDFreeMemory((_buffer))

#define MrvlZeroMemory(_buffer, _size)      memset((_buffer), 0, (_size)) 
#define MrvlMoveMemory(_dest, _src, _size)  memmove((_dest), (_src), (_size)) 


#define MRVL_BT_BUFFER_HEADER_SIZE          4
#define MRVL_BT_PACKET_SIZE_R               65536
#define MRVL_BT_PACKET_SIZE_W               65536

#define MRVL_BT_SCO_DEFAULT_SAMPLE_SIZE             8
#define MRVL_BT_SCO_DEFAULT_WRITE_LOW_NUM_PACKETS   2
#define MRVL_BT_SCO_DEFAULT_WRITE_HIGH_NUM_PACKETS  4
#define MRVL_BT_SCO_DEFAULT_PACKET_SIZE             51

//#define MRVDRV_SIZE_OF_CMD_BUFFER        0x00000c00    // 3K
#define MRVDRV_SIZE_OF_CMD_BUFFER        (2 * 1024)
#define MRVDRV_NUM_OF_CMD_BUFFER         0x00000040

#define MAX_TX_PACKETS                   64
#define MRVDRV_RX_PKT_QUEUE_DEPTH        20
#define MRVDRV_TX_PKT_QUEUE_DEPTH        20

#define HCI_MAX_FRAME_SIZE               MRVL_BT_PACKET_SIZE_R

/* This is for firmware specific length */
#define EXTRA_LEN                        36

#define SDIO_HEADER_LEN                  4
#define BT_UPLD_SIZE                     2312
#define SD_BLOCK_SIZE                    32


#define FN(x)   (x)
#define FN0     FN(0)
#define FN1     FN(1)
#define FN2     FN(2)
#define FN3     FN(3)
#define FN4     FN(4)
#define FN5     FN(5)
#define FN6     FN(6)
#define FN7     FN(7)

#define FW_DNLD_FUNC        FN1
#define WLAN_FUNC           FN1
#define BT_FUNC             FN2


#define MRVDRV_BT_RX_PACKET_BUFFER_SIZE  (HCI_MAX_FRAME_SIZE + EXTRA_LEN)

#define ALLOC_BUF_SIZE \
(((MAX(MRVDRV_BT_RX_PACKET_BUFFER_SIZE, MRVDRV_SIZE_OF_CMD_BUFFER) + \
   SDIO_HEADER_LEN + SD_BLOCK_SIZE - 1) / SD_BLOCK_SIZE) * SD_BLOCK_SIZE)


typedef enum _MRVL_STATUS {
    MRVL_STATUS_SUCCESS = 0,
    MRVL_STATUS_FAILURE,
    MRVL_STATUS_NOT_ACCEPTED,
    MRVL_STATUS_NOT_SUPPORTED,
    MRVL_STATUS_INVALID_LENGTH,
    MRVL_STATUS_INVALID_DATA,
    MRVL_STATUS_RESOURCES,
    MRVL_STATUS_BUFFER_TOO_SHORT,
} MRVL_STATUS;


enum HCI_PACKET_TYPE {
    HCI_COMMAND_PKT = 1,
    HCI_ACLDATA_PKT = 2,
    HCI_SCODATA_PKT = 3,
    HCI_EVENT_PKT   = 4,
    HCI_VENDOR_PKT  = 0xFE,
};

#pragma pack(1)
typedef struct _SD_TRANSPORT_HEADER
{
    union
    {
        struct
        {
            UCHAR   PacketLength[3];
            UCHAR   ServiceID;
        } AsUCHAR;
        ULONG   AsULONG;
    } u;
} SD_TRANSPORT_HEADER, *PSD_TRANSPORT_HEADER;
#pragma pack()


// definition for Node of Rx Packet Queue
typedef struct _PacketQueueNode
{
    struct _PacketQueueNode *Next;
    PUCHAR pPacketBuf;
} PACKET_QUEUE_NODE, *PPACKET_QUEUE_NODE;


//
// Command control node status
// Driver use status field to maintian command control nodes
//
#define MRVDRV_CMD_CTRL_NODE_STATUS_IDLE        0x0000
#define MRVDRV_CMD_CTRL_NODE_STATUS_PENDING     0x0001
#define MRVDRV_CMD_CTRL_NODE_STATUS_PROCESSING  0x0002

#define MRVDRV_FW_STATUS_READY                  0x5A
#define MRVDRV_FW_DL_RDY_FOR_NEXT_BLOCK         0xAA

#define SDIO_MAX_PKT_LEN                    1550
#define SDIO_MAX_CMD_LEN                    1024

#pragma pack(1)
typedef struct _SDIO_TX_PKT_T
{
    UCHAR       Pkt[SDIO_MAX_PKT_LEN];
} SDIO_TX_PKT_T, *PSDIO_TX_PKT_T;

typedef struct _SDIO_TX_PKT
{
    USHORT  Len;
    union 
    {
        SDIO_TX_PKT_T  TxDataBuf;
        UCHAR          CmdBuf[SDIO_MAX_CMD_LEN];
    } Buf;
} SDIO_TX_PKT, *PSDIO_TX_PKT;
#pragma pack()


#ifdef ALIGN_32BYTES
#define ALIGN32(typ, ptr, tmp) ((ptr) = (typ *)( ((ULONG)(&(tmp)) + 32) & ~0x1F ))

#define STRUCT_ALIGN32(strct, ptr, tmp) \
    strct *ptr; struct { strct tmp; UCHAR   pad[32]; } tmp
#endif

//
// Q data structures and useful Q operation macros. Right now Tx and command
// routines are using these macros to queue and retrieve packets and 
// commands.
// Driver cast queued item to Q_NODE type and link it to the queue
// maintained by Q_KEEPER
//
typedef struct _Q_NODE
{
    struct _Q_NODE *Next;
} Q_NODE, *PQ_NODE;

//
// Q_KEEPER maintains the first and the last item on the queue
//
typedef struct _Q_KEEPER
{
    PQ_NODE First;
    PQ_NODE Last;
} Q_KEEPER, *PQ_KEEPER;

//
// Q_KEEPER initialization macro
//
#define InitializeQKeeper(QKeeper)             \
{                                              \
    (QKeeper)->First = (QKeeper)->Last = NULL; \
}

//
// Q_NODE push macro
//
#define InsertQNodeFromHead(QKeeper, QNode)     \
{                                               \
    ((PQ_NODE)QNode)->Next = (QKeeper)->First;  \
    (QKeeper)->First = (PQ_NODE)(QNode);        \
    if ((QKeeper)->Last == NULL)                \
        (QKeeper)->Last = (PQ_NODE)(QNode);     \
}

//
// Q_NODE queue macro
//
#define InsertQNodeAtTail(QKeeper, QNode)         \
{                                                 \
    ((PQ_NODE)QNode)->Next = NULL;                \
    if ((QKeeper)->Last)                          \
        (QKeeper)->Last->Next = (PQ_NODE)(QNode); \
    else                                          \
        (QKeeper)->First = (PQ_NODE)(QNode);      \
    (QKeeper)->Last = (PQ_NODE)(QNode);           \
}

//
// Q_NODE pop macro
//
#define PopFirstQNode(QKeeper)                         \
    (QKeeper)->First;                                  \
    {                                                  \
        if ((QKeeper)->First)                          \
            (QKeeper)->First = (QKeeper)->First->Next; \
        if ((QKeeper)->First == NULL)                  \
            (QKeeper)->Last = NULL;                    \
    }

//
// Q_KEEPER empty macro
//
#define IsQEmpty(QKeeper) ((QKeeper)->First == NULL)


/** Marvell vendor packet */
#define MRVL_VENDOR_PKT             0xFE
/** Bluetooth command : Sleep mode */
#define BT_CMD_AUTO_SLEEP_MODE      0x23
/** Bluetooth command : Host Sleep configuration */
#define BT_CMD_HOST_SLEEP_CONFIG    0x59
/** Bluetooth command : Host Sleep enable */
#define BT_CMD_HOST_SLEEP_ENABLE    0x5A
/** Bluetooth command : Module Configuration request */
#define BT_CMD_MODULE_CFG_REQ       0x5B
/** Sub Command: Module Bring Up Request */
#define MODULE_BRINGUP_REQ          0xF1
/** Sub Command: Module Shut Down Request */
#define MODULE_SHUTDOWN_REQ         0xF2
/** Sub Command: Host Interface Control Request */
#define MODULE_INTERFACE_CTRL_REQ   0xF5

/** Bluetooth event : Power State */
#define BT_EVENT_POWER_STATE        0x20

/** Bluetooth Power State : Enable */
#define BT_PS_ENABLE        0x02
/** Bluetooth Power State : Disable */
#define BT_PS_DISABLE       0x03
/** Bluetooth Power State : Sleep */
#define BT_PS_SLEEP         0x01
/** Bluetooth Power State : Awake */
#define BT_PS_AWAKE         0x02

/** OGF */
#define OGF                 0x3F

/** Host Sleep activated */
#define HS_ACTIVATED        0x01
/** Host Sleep deactivated */
#define HS_DEACTIVATED      0x00

/** Power Save sleep */
#define PS_SLEEP            0x01
/** Power Save awake */
#define PS_AWAKE            0x00

#define BT_CMD_SUCCESS      0x00

#define WAIT_PS_AWAKE_TIMEOUT   3000
#define WAIT_CMD_RESP_TIMEOUT   3000

#define CMD_OPTION_NO_WAIT      0x00
#define CMD_OPTION_WAIT_RESP    0x01


#pragma pack(1)
typedef struct _BT_CMD {
    /** OCF OGF */
    USHORT ocf_ogf;
    /** Length */
    UCHAR  length;
    /** Data */
    UCHAR  data[4];
} BT_CMD;

typedef struct _BT_EVENT {
    /** Event Counter */
    UCHAR  EC;
    /** Length */
    UCHAR  length;
    /** Data */
    UCHAR  data[4];
} BT_EVENT;
#pragma pack()

// Structure describing Registry values
#pragma pack(1)
typedef struct _REG_VALUE_DESCR 
{
    LPWSTR val_name;
    DWORD  val_type;
    PBYTE  val_data;
} REG_VALUE_DESCR, *PREG_VALUE_DESCR;
#pragma pack()

#endif  /* #ifndef _BT_DEF_H_ */
